<template>
  <a-card
    :bordered="false"
    class="search-wrapper"
    :style="{ 'margin-bottom': list.length > 2 * columnNum ? '54px' : '24px' }"
  >
    <a-spin :spinning="loading">
      <div class="serch-header">
        <slot name="header"></slot>
      </div>
      <a-form v-bind="$attrs" labelAlign="right" :form="form" :labelCol="labelCol" :wrapperCol="wrapperCol">
        <a-row :gutter="16" type="flex">
          <template v-for="(item, index) in list">
            <a-col
              :md="14"
              :lg="12"
              :xl="8"
              :sm="24"
              v-if="index < 2 * columnNum"
              :key="index">
              <a-form-item :label="item.label">
                <span v-if="item.extra" slot="extra" class="extra">温馨提示：{{ item.extra }}</span>
                <template v-if="item.slot">
                  <slot :name="item.slot"></slot>
                </template>
                <template v-else>
                  <component
                    :is="componentType(item.type)"
                    :allowClear="handleAllowClear(item)"
                    autocomplete="off"
                    @pressEnter="handleSearch"
                    v-bind="item.props"
                    v-on="item.methods"
                    v-decorator="[
                      item.fields,
                      {
                        rules: item.validate,
                        initialValue: item.initialValue || undefined,
                        valuePropName: item.type === 'switch' ? 'checked' : 'value',
                        getValueFromEvent(event) {
                          if (item.type.toLocaleUpperCase() === 'INPUT') {
                            return event.target.value.trim()
                          } else {
                            return event
                          }
                        },
                      },
                    ]"
                  ></component>
                </template>
              </a-form-item>
            </a-col>
          </template>
          <collapseTransition v-if="list.length > 2 * columnNum">
            <div v-show="showMore" style="width: 100%">
              <template v-for="(item, index) in list">
                <a-col
                  :md="14"
                  :lg="12"
                  :xl="8"
                  :sm="24"
                  v-if="index >= 2 * columnNum"
                  :key="index">
                  <a-form-item :label="item.label">
                    <span v-if="item.extra" slot="extra" class="extra">温馨提示：{{ item.extra }}</span>
                    <template v-if="item.slot">
                      <slot :name="item.slot"></slot>
                    </template>
                    <template v-else>
                      <component
                        :is="componentType(item.type)"
                        :allowClear="handleAllowClear(item)"
                        autocomplete="off"
                        v-on="item.methods"
                        v-bind="item.props"
                        v-decorator="[
                          item.fields,
                          {
                            rules: item.validate,
                            initialValue: item.initialValue || undefined,
                            valuePropName: item.type === 'switch' ? 'checked' : 'value',
                            getValueFromEvent(event) {
                              if (item.type.toLocaleUpperCase() === 'INPUT') {
                                return event.target.value.trim()
                              } else {
                                return event
                              }
                            },
                          },
                        ]"
                      ></component>
                    </template>
                  </a-form-item>
                </a-col>
              </template>
            </div>
          </collapseTransition>
        </a-row>
        <a-row>
          <a-col :md="14" :lg="12" :xl="8" :sm="24">
            <a-form-item label="操作">
              <y-button type="primary" @click="handleSearch">查询</y-button>
              <y-button type="default" @click="handleReset">重置</y-button>
              <slot name="action"></slot>
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
      <div class="serch-footer">
        <slot name="footer"></slot>
      </div>
      <a-tooltip :title="showMore ? '收起' : '展开'" placement="bottom" :mouseLeaveDelay="0">
        <div class="more" v-if="list.length > 2 * columnNum" @click="showMore = !showMore">
          <a-icon :type="showMore ? 'caret-up' : 'caret-down'"> </a-icon>
        </div>
      </a-tooltip>
    </a-spin>
  </a-card>
</template>

<script>
/**
 * @Description：基于antd 封装的搜索框
 * @Author：Answer™
 * @Version：1.0.3
 * @Date：2022-8-19 10:48:48
 * @LastEditors：Answer™
 * @LastEditTime：2022-9-30 09:16:44
 * @property：labelCol Object label占比
 * @property：wrapperCol Object wrappe占比
 * @property：columnNum Number 一行几个
 * @property more Boolean 默认是否展开更多
 * @property loading Boolean 加载状态
 * @property：list Array  搜索数组
 * {
 *  type: '' input | select | radio | check | week | month | date | year | range | switch
 *  label: '' 显示的label
 *  fields: '' 绑定字段名称
 *  extra： '' 提示文字
 *  validate: [] 表单验证
 *  initialValue: '' 默认值
 *  props: {} 组件参数
 *  methods: {} 组件事件
 * }
 * @slot header 顶部自定义
 * @slot footer 尾部自定义
 * @event：search 搜索事件
 * @event：reset 重置事件
 */
import { Input, Switch, Radio, Checkbox, Select, DatePicker, Cascader, TreeSelect } from 'ant-design-vue'
import collapseTransition from './collapseTransition'
import yearPicker from '../yearPicker'
import lodash from 'lodash'
const { Group: checkboxGroup } = Checkbox
const { Group: RadioGroup } = Radio
const { MonthPicker, RangePicker, WeekPicker } = DatePicker
export default {
  components: {
    collapseTransition,
    yearPicker
  },
  props: {
    labelCol: {
      type: Object,
      default: () => {
        return { span: 6 }
      }
    },
    wrapperCol: {
      type: Object,
      default: () => {
        return { span: 18 }
      }
    },
    columnNum: {
      type: Number,
      default: 3
    },
    more: {
      type: Boolean,
      default: false
    },
    loading: {
      type: Boolean,
      default: false
    },
    list: {
      type: Array,
      default: () => [
        {
          label: '搜索名称', // 设置标签的label名
          fields: 'name', // value(Vmode)绑定的字段名
          type: 'input' // 设置标签类型为 input date select radio等
        }
      ]
    }
  },
  computed: {
    componentType () {
      return (type) => {
        const componentMap = new Map([
          ['INPUT', Input],
          ['SELECT', Select],
          ['SWITCH', Switch],
          ['CHECKBOX', checkboxGroup],
          ['DATE', DatePicker],
          ['RADIO', RadioGroup],
          ['MONTH', MonthPicker],
          ['WEEK', WeekPicker],
          ['RANGE', RangePicker],
          ['CASCADER', Cascader],
          ['YEAR', yearPicker],
          ['TREESELECT', TreeSelect]
        ])
        return componentMap.get(type.toLocaleUpperCase())
      }
    }
  },
  data () {
    return {
      form: this.$form.createForm(this),
      showMore: false
    }
  },
  mounted () {
    this.showMore = this.more
  },
  methods: {
    handleAllowClear (item) {
      const { type } = item
      if (type.toLocaleUpperCase() !== 'SELECT') {
        return false
      } else {
        if (item.props.hasOwnProperty('allowClear')) {
          return item.props.allowClear
        } else {
          return true
        }
      }
    },
    handleSearch: lodash.throttle(function () {
      this.form.validateFields((err, values) => {
        if (!err) {
          this.$emit(
            'search',
            lodash.omitBy(values, (item) => !item)
          )
        }
      })
    }, 500),
    handleReset: lodash.throttle(function () {
      this.reset()
      this.$emit('reset', {})
    }, 500),
    // 获取值  手动获取搜索结果
    getFieldsValue (params) {
      return this.form.getFieldsValue(params)
    },
    // 重置数据
    setFieldsValue (params) {
      return this.form.setFieldsValue(params)
    },
    // 只重置表单 不触发向父级传递
    reset () {
      this.form.resetFields()
    }
  }
}
</script>
<style lang="less" scoped>
@import '~ant-design-vue/dist/antd.less';
.search-wrapper {
  position: relative;
  .ant-form-inline {
    .ant-form-item {
      display: flex;
      margin-right: 0;
      &:not(:last-child) {
        margin-bottom: 24px;
      }

      .ant-form-item-control-wrapper {
        flex: 1 1;
        display: inline-block;
        vertical-align: middle;
      }

      > .ant-form-item-label {
        line-height: 32px;
        padding-right: 12px;
        width: 90px;
      }
      .ant-form-item-control {
        height: 32px;
        line-height: 32px;
      }
    }
  }
  .more {
    position: absolute;
    bottom: -30px;
    left: 50%;
    transform: translateX(-50%);
    width: 200px;
    height: 30px;
    line-height: 20px;
    border-radius: 0px 0px 10px 10px;
    background-color: #fff;
    text-align: center;
    border: 1px solid color(~`colorPalette('@{primary-color}', 2) `);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: @primary-color;
    font-size: 20px;
    transition: all 0.3s;
    &:hover {
      font-size: 26px;
    }
  }
  .extra {
    color: color(~`colorPalette('@{warning-color}', 5) `);
    font-size: 12px;
  }

  /deep/ .ant-calendar-picker {
    width: 100% !important;
  }
}
</style>
